package com.pj.compose.activity

import android.Manifest
import android.annotation.SuppressLint
import android.app.Activity
import android.bluetooth.*
import android.content.BroadcastReceiver
import android.content.Context
import android.content.Intent
import android.content.IntentFilter
import android.os.Build
import android.os.Bundle
import android.view.MenuItem
import androidx.activity.ComponentActivity
import androidx.activity.compose.setContent
import androidx.activity.result.contract.ActivityResultContracts
import androidx.annotation.RequiresApi
import androidx.compose.foundation.layout.*
import androidx.compose.material3.ExperimentalMaterial3Api
import androidx.compose.material3.Scaffold
import androidx.compose.runtime.getValue
import androidx.compose.ui.Modifier
import androidx.compose.ui.graphics.Color
import androidx.core.view.WindowCompat
import androidx.hilt.navigation.compose.hiltViewModel
import com.blankj.utilcode.util.ConvertUtils
import com.blankj.utilcode.util.LogUtils
import com.blankj.utilcode.util.ToastUtils
import com.google.accompanist.systemuicontroller.rememberSystemUiController
import com.pj.compose.darkThemeState
import com.pj.compose.themeTypeState
import com.pj.compose.ui.page.other.bluetooth.BluetoothHidPage
import com.pj.compose.ui.theme.CustomThemeManager
import com.pj.compose.ui.theme.ThemeType
import com.pj.compose.viewmodel.BluetoothViewModel
import java.io.IOException
import java.util.UUID

class BluetoothActivity : ComponentActivity() {

    private lateinit var vm: BluetoothViewModel
    private var connectThread: ConnectThread? = null//连接线程
    private val bluetoothPermission =
        registerForActivityResult(ActivityResultContracts.StartActivityForResult()) {
            if (it.resultCode == Activity.RESULT_OK) {
                if (isEnableBluetooth()) {
                    vm.isBluetoothEnabled = true
                    discoveryBluetooth()
                } else {
                    ToastUtils.showLong("蓝牙开启失败")
                }
            }
        }

    @SuppressLint("MissingPermission")
    private val scanPermissionLauncher =
        registerForActivityResult(ActivityResultContracts.RequestPermission()) {
            if (it) {
                getBoundDevices()
                bluetoothAdapter?.startDiscovery()
            } else {
                ToastUtils.showLong("开启蓝牙扫描失败")
            }
        }

    var bluetoothHeadset: BluetoothHeadset? = null
    private val bluetoothAdapter = BluetoothAdapter.getDefaultAdapter()
    private val receiver = object : BroadcastReceiver() {
        @SuppressLint("MissingPermission")
        override fun onReceive(context: Context, intent: Intent) {
            when (intent.action) {
                BluetoothDevice.ACTION_FOUND -> {
                    val device: BluetoothDevice? =
                        intent.getParcelableExtra(BluetoothDevice.EXTRA_DEVICE)
                    if (device != null && !vm.foundDevices.contains(device))
                        vm.foundDevices.add(device)
                }
            }
        }
    }


    val profileListener = object : BluetoothProfile.ServiceListener {
        override fun onServiceConnected(profile: Int, proxy: BluetoothProfile) {
            if (profile == BluetoothProfile.HEADSET) {
                bluetoothHeadset = proxy as BluetoothHeadset
            }
        }

        override fun onServiceDisconnected(profile: Int) {
            if (profile == BluetoothProfile.HEADSET) {
                bluetoothHeadset = null
            }
        }
    }

    @RequiresApi(Build.VERSION_CODES.S)
    @OptIn(ExperimentalMaterial3Api::class)
    override fun onCreate(savedInstanceState: Bundle?) {
        super.onCreate(savedInstanceState)
        setContent {
            //初始化viewModel
            vm = hiltViewModel()
            vm.isBluetoothEnabled = isEnableBluetooth()

            val themType: ThemeType by themeTypeState
            val isDarkTheme: Boolean by darkThemeState
            WindowCompat.setDecorFitsSystemWindows(window, false)
            CustomThemeManager.WithTheme(type = themType, darkTheme = isDarkTheme) {
                rememberSystemUiController().setStatusBarColor(
                    Color.Transparent, darkIcons = !darkThemeState.value
                )
                Scaffold(
                    modifier = Modifier
//                        .windowInsetsPadding(WindowInsets.systemBars.only(WindowInsetsSides.Bottom))
                        .fillMaxSize()
                ) {
                    BluetoothHidPage(
                        modifier = Modifier
                            .padding(bottom = it.calculateBottomPadding())
                            .fillMaxSize(),
                        vm = vm,
                        onStart = { startBluetooth() },
                        onScan = { scanBluetooth() },
                        onFoundItemClick = {
//                                dev -> connectBluetooth(dev)
                        },
                        onHid = {}
                    )
                }

            }
        }
        registerBluetoothBroadcast()
    }


    override fun onDestroy() {
        super.onDestroy()
        if (connectThread != null) {
            connectThread!!.cancel()
            connectThread = null
        }
        unregisterReceiver(receiver)
    }

    private fun isEnableBluetooth(): Boolean {
        return bluetoothAdapter.isEnabled
    }


    /**
     * 扫描蓝牙设备
     */
    private fun scanBluetooth() {
        scanPermissionLauncher.launch(if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.S) Manifest.permission.BLUETOOTH_SCAN else Manifest.permission.BLUETOOTH_ADMIN)
    }

    /**
     * 开启蓝牙
     */
    private fun startBluetooth() {
        bluetoothPermission.launch(Intent(BluetoothAdapter.ACTION_REQUEST_ENABLE))
    }

    /**
     * 连接蓝牙设备
     */
    private fun connectBluetooth(device: BluetoothDevice) {
        if (connectThread == null) {
            connectThread = ConnectThread(device = device)
            connectThread!!.start()
        } else {

        }
    }

    /**
     * 可连接的蓝牙设备列表
     */
    @SuppressLint("MissingPermission")
    private fun getBoundDevices() {
        vm.boundDevices.clear()
        val pairedDevices: Set<BluetoothDevice>? = bluetoothAdapter?.bondedDevices
        vm.boundDevices.addAll(pairedDevices ?: emptySet())
    }

    /**
     * 监听发现蓝牙设备的系统广播
     */
    private fun registerBluetoothBroadcast() {
        val filter = IntentFilter(BluetoothDevice.ACTION_FOUND)
        registerReceiver(receiver, filter)
    }

    /**
     * 让其他设备可以发现当前蓝牙设备
     */
    private fun discoveryBluetooth() {
        val discoverableIntent: Intent =
            Intent(BluetoothAdapter.ACTION_REQUEST_DISCOVERABLE).apply {
                putExtra(BluetoothAdapter.EXTRA_DISCOVERABLE_DURATION, 300)
            }
        startActivity(discoverableIntent)
    }


    //    private val uuidString = "A877C9C9-5A43-4BB6-9EDA-C9D64FCD8064"
    private val uuidString = "00001105-0000-1000-8000-00805f9B34FB"

    /**
     * 蓝牙作为服务器连接
     */
    @SuppressLint("MissingPermission")
    private inner class AcceptThread : Thread() {
        //随机的uuid
        private val mmServerSocket: BluetoothServerSocket? by lazy(LazyThreadSafetyMode.NONE) {
            bluetoothAdapter?.listenUsingInsecureRfcommWithServiceRecord(
                bluetoothAdapter.name,
                UUID.fromString(uuidString)
            )
        }

        override fun run() {
            // Keep listening until exception occurs or a socket is returned.
            var shouldLoop = true
            while (shouldLoop) {
                val socket: BluetoothSocket? = try {
                    mmServerSocket?.accept()
                } catch (e: IOException) {
                    LogUtils.e("Socket's accept() method failed", e)
                    shouldLoop = false
                    null
                }
                socket?.also {
                    manageMyConnectedSocket(it)
                    mmServerSocket?.close()
                    shouldLoop = false
                }
            }
        }

        //处理蓝牙数据
        private fun manageMyConnectedSocket(socket: BluetoothSocket) {
            val input = socket.inputStream
            val bytes = ConvertUtils.inputStream2Bytes(input)
            LogUtils.i(bytes)
        }

        // Closes the connect socket and causes the thread to finish.
        fun cancel() {
            try {
                mmServerSocket?.close()
            } catch (e: IOException) {
                LogUtils.e("Could not close the connect socket", e)
            }
        }
    }

    /**
     * 蓝牙作为客户端连接
     */
    @SuppressLint("MissingPermission")
    private inner class ConnectThread(device: BluetoothDevice) : Thread() {

        private val mmSocket: BluetoothSocket? by lazy(LazyThreadSafetyMode.NONE) {
            device.createRfcommSocketToServiceRecord(UUID.fromString(uuidString))
        }

        override fun run() {
            // Cancel discovery because it otherwise slows down the connection.
            bluetoothAdapter?.cancelDiscovery()

            mmSocket?.use { socket ->
                // Connect to the remote device through the socket. This call blocks
                // until it succeeds or throws an exception.
                try {
                    socket.connect()
                    LogUtils.e("蓝牙链接成功！")
                } catch (e: Exception) {
                    e.printStackTrace()
                    LogUtils.e(e)
                }


                // The connection attempt succeeded. Perform work associated with
                // the connection in a separate thread.
//                manageMyConnectedSocket(socket)
            }
        }

        // Closes the client socket and causes the thread to finish.
        fun cancel() {
            try {
                mmSocket?.close()
                stop()
            } catch (e: IOException) {
                LogUtils.e("Could not close the client socket", e)
            }
        }
    }

    override fun onOptionsItemSelected(item: MenuItem): Boolean {
        if (item.itemId == android.R.id.home) {
            onBackPressed()
        }
        return super.onOptionsItemSelected(item)
    }
}